package com.ssy.lingxi.platform.template.service.serviceimpl.web;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.template.PageTemplateTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.template.api.model.dto.inner.OpenMroInnerDTO;
import com.ssy.lingxi.platform.template.service.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.template.service.constant.PageTemplateEnvironmentEnum;
import com.ssy.lingxi.platform.template.service.constant.PageTemplateShelfEnum;
import com.ssy.lingxi.platform.template.service.entity.adorn.PageTemplate;
import com.ssy.lingxi.platform.template.service.entity.adorn.PlatformTemplateAdorn;
import com.ssy.lingxi.platform.template.service.entity.door.*;
import com.ssy.lingxi.platform.template.service.model.bo.MemberBO;
import com.ssy.lingxi.platform.template.service.model.bo.SelfMemberBO;
import com.ssy.lingxi.platform.template.service.model.bo.WebPlatformBO;
import com.ssy.lingxi.platform.template.service.model.dto.common.IdDTO;
import com.ssy.lingxi.platform.template.service.model.dto.common.OpenMroDTO;
import com.ssy.lingxi.platform.template.service.model.dto.common.SiteIdShopIdDTO;
import com.ssy.lingxi.platform.template.service.model.dto.common.TemplateInfoDTO;
import com.ssy.lingxi.platform.template.service.model.dto.web.PageTemplateTypeDTO;
import com.ssy.lingxi.platform.template.service.model.dto.web.ShelfTemplateDTO;
import com.ssy.lingxi.platform.template.service.model.vo.adorn.*;
import com.ssy.lingxi.platform.template.service.model.vo.web.PageTemplateVO;
import com.ssy.lingxi.platform.template.service.model.vo.web.UseWebPlatformTemplateVO;
import com.ssy.lingxi.platform.template.service.repository.MemberChannelRepository;
import com.ssy.lingxi.platform.template.service.repository.MemberShopRepository;
import com.ssy.lingxi.platform.template.service.repository.PageTemplateRepository;
import com.ssy.lingxi.platform.template.service.repository.PlatformTemplateAdornRepository;
import com.ssy.lingxi.platform.template.service.service.web.PageTemplateWebService;
import com.ssy.lingxi.search.api.feign.ITemplateFeign;
import com.ssy.lingxi.search.api.model.request.TemplateCommoditySearchRequest;
import com.ssy.lingxi.search.api.model.response.CommoditySearchResponse;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * web - 页面模板 - 业务实现层
 *
 * @author fhj
 * @version 2.0.0
 * @date 2020/12/11
 */
@Slf4j
@Service
public class PageTemplateWebServiceImpl implements PageTemplateWebService {

    @Resource
    private PageTemplateRepository pageTemplateRepository;
    @Resource
    private MemberShopRepository memberShopRepository;
    @Resource
    private MemberChannelRepository memberChannelRepository;
    @Resource
    private PlatformTemplateAdornRepository platformTemplateAdornRepository;
    @Resource
    private ITemplateFeign templateFeign;
    @Resource
    private JPAQueryFactory jpaQueryFactory;

    @Override
    @ApiOperation(value = "获取使用中的WEB平台首页模板")
    public Wrapper<UseWebPlatformTemplateVO> findPlatformTemplate(Long siteId, String provinceCode, String cityCode) {
        //根据适用环境、模板类型、使用状态、站点ID获取平台首页模板
        PageTemplate pageTemplate = pageTemplateRepository.findByEnvironmentAndTypeAndStatusAndSiteId(
                PageTemplateEnvironmentEnum.WEB.getCode(),
                PageTemplateTypeEnum.PLATFORM.getCode(),
                CommonBooleanEnum.YES.getCode(),
                siteId
        );
        if (pageTemplate == null) {
            return Wrapper.fail(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //根据模板ID获取WEB平台首页模板装修
        PlatformTemplateAdorn platformTemplateAdorn = platformTemplateAdornRepository.findByTemplateId(pageTemplate.getId());
        List<WebPlatformBO> webPlatformBOList = new ArrayList<>();
        if (platformTemplateAdorn != null) {
            webPlatformBOList = platformTemplateAdorn.getList();
            if (webPlatformBOList.size() > 0) {
                //1-对物流公司进行区域筛选
                this.handlingLogisticsCompanies(webPlatformBOList, provinceCode, cityCode);
                //2-对加工企业进行区域筛选
                this.handlingProcessCompanies(webPlatformBOList, provinceCode, cityCode);
                //3-对商品进行区域筛选
                this.handlingGoods(webPlatformBOList, provinceCode, cityCode);
                //4-对实力商家进行区域筛选
                this.handlingMerchant(webPlatformBOList, provinceCode, cityCode);
            }
        }

        //封装
        UseWebPlatformTemplateVO vo = new UseWebPlatformTemplateVO();
        vo.setId(pageTemplate.getId());
        vo.setFileName(pageTemplate.getFileName());
        vo.setList(platformTemplateAdorn != null ? webPlatformBOList : null);

        return Wrapper.success(vo);
    }

    /**
     * 对实力商家进行区域筛选
     *
     * @param webPlatformBOList 装修数据
     * @param provinceCode      省code
     * @param cityCode          城市code
     */
    private void handlingMerchant(List<WebPlatformBO> webPlatformBOList, String provinceCode, String cityCode) {
        WebPlatformBO webPlatformBO = webPlatformBOList.stream().filter(w -> "merchant".equals(w.getName())).findFirst().orElse(null);
        if (webPlatformBO != null) {
            //解析数据
            String merchantStr = JSONObject.toJSONString(webPlatformBO.getContent());
            List<StoreVO> resp = JSONObject.parseArray(merchantStr, StoreVO.class);
            if (!CollectionUtils.isEmpty(resp)) {
                //获取全部实力商家id
                List<Long> ids = resp.stream().map(StoreVO::getId).collect(toList());
                QMemberShop qMemberShop = QMemberShop.memberShop;
                BooleanBuilder builder = new BooleanBuilder();
                builder.and(qMemberShop.id.in(ids));
                //搜索条件 - 省编码。
                if (org.apache.commons.lang.StringUtils.isNotBlank(provinceCode)) {
                    builder.and(
                            qMemberShop.provincesCodeList.like("%" + provinceCode + "%")
                                    .or(qMemberShop.provincesCodeList.eq("0"))
                    );
                }
                //搜索条件 - 市编码。
                if (StringUtils.isNotBlank(cityCode)) {
                    builder.and(
                            qMemberShop.cityCodeList.like("%" + cityCode + "%")
                                    .or(qMemberShop.cityCodeList.eq("0"))
                    );
                }
                List<MemberShop> memberShops = jpaQueryFactory.select(qMemberShop).from(qMemberShop).where(builder).fetch();
                List<Long> list = memberShops.stream().map(MemberShop::getId).collect(toList());
                resp = resp.stream().filter(r -> list.contains(r.getId())).collect(toList());
            }
            webPlatformBO.setContent(resp);
        }
    }


    /**
     * 对商品进行区域筛选
     *
     * @param webPlatformBOList 装修数据
     * @param provinceCode      省code
     * @param cityCode          城市code
     */
    private void handlingGoods(List<WebPlatformBO> webPlatformBOList, String provinceCode, String cityCode) {
        WebPlatformBO webPlatformBO = webPlatformBOList.stream().filter(w -> "goods".equals(w.getName())).findFirst().orElse(null);
        if (webPlatformBO != null) {
            //解析数据
            String goodsStr = JSONObject.toJSONString(webPlatformBO.getContent());
            JSONArray resp = JSONObject.parseArray(goodsStr);
            JSONArray result = new JSONArray();
            if (resp != null) {
                resp.forEach(r -> {
                    String goodListStr = JSONObject.toJSONString(r);
                    JSONObject goodJson = JSONObject.parseObject(goodListStr);
                    String goodsList = String.valueOf(goodJson.get("goodsList"));
                    List<GoodsVO> goodsVOS = JSONObject.parseArray(goodsList, GoodsVO.class);
                    if (!CollectionUtils.isEmpty(goodsVOS)) {
                        //获取全部商品id
                        List<Long> ids = goodsVOS.stream().map(GoodsVO::getGoodsId).collect(Collectors.toList());
                        //调用搜索服务筛选商品数据
                        if (ids.size() > 0) {
                            TemplateCommoditySearchRequest request = new TemplateCommoditySearchRequest();
                            request.setCurrent(1);
                            request.setPageSize(ids.size());
                            request.setIdInList(ids);
                            request.setProvinceCode(provinceCode);
                            request.setCityCode(cityCode);
                            Wrapper<PageData<CommoditySearchResponse>> commodityList = templateFeign.searchCommodityList(request);
                            List<CommoditySearchResponse> responseList = commodityList.getData().getData();
                            if (responseList != null) {
                                List<Long> goodsIdList = responseList.stream().map(CommoditySearchResponse::getId).collect(toList());
                                goodJson.put("goodsIdList", goodsIdList);
                                goodsVOS = goodsVOS.stream().filter(g -> goodsIdList.contains(g.getGoodsId())).collect(toList());
                                goodJson.put("goodsList", goodsVOS);
                            }
                        }
                    }

                    result.add(goodJson);
                });
                webPlatformBO.setContent(result);
            }
        }
    }

    /**
     * 对加工企业进行区域筛选
     *
     * @param webPlatformBOList 装修数据
     * @param provinceCode      省code
     * @param cityCode          城市code
     */
    private void handlingProcessCompanies(List<WebPlatformBO> webPlatformBOList, String provinceCode, String cityCode) {
        WebPlatformBO webPlatformBO = webPlatformBOList.stream().filter(w -> "process".equals(w.getName())).findFirst().orElse(null);
        if (webPlatformBO != null) {
            //解析数据
            String processStr = JSONObject.toJSONString(webPlatformBO.getContent());
            JSONObject resp = JSONObject.parseObject(processStr);
            if (resp != null) {
                String processMerchantList = String.valueOf(resp.get("processMerchantList"));
                List<ProcessVO> processVOS = JSONObject.parseArray(processMerchantList, ProcessVO.class);
                //获取全部加工企业id
                List<Long> ids = processVOS.stream().map(ProcessVO::getId).collect(Collectors.toList());
                //根据id获取加工企业的全部信息
                QMemberProcess qMemberProcess = QMemberProcess.memberProcess;
                BooleanBuilder builder = new BooleanBuilder();
                builder.and(qMemberProcess.id.in(ids));
                //搜索条件 - 省编码。
                if (org.apache.commons.lang.StringUtils.isNotBlank(provinceCode)) {
                    builder.and(
                            qMemberProcess.provincesCodeList.like("%" + provinceCode + "%")
                                    .or(qMemberProcess.provincesCodeList.eq("0"))
                    );
                }
                //搜索条件 - 市编码。
                if (StringUtils.isNotBlank(cityCode)) {
                    builder.and(
                            qMemberProcess.cityCodeList.like("%" + cityCode + "%")
                                    .or(qMemberProcess.cityCodeList.eq("0"))
                    );
                }
                List<MemberProcess> memberProcesses = jpaQueryFactory.select(qMemberProcess).from(qMemberProcess).where(builder).fetch();
                List<Long> collect = memberProcesses.stream().map(MemberProcess::getId).collect(toList());
                processVOS = processVOS.stream().filter(m -> collect.contains(m.getId())).collect(toList());
                resp.put("processMerchantList", processVOS);
                webPlatformBO.setContent(resp);
            }
        }
    }


    /**
     * 对物流公司进行区域赛选
     *
     * @param webPlatformBOList 装修数据
     * @param provinceCode      省code
     * @param cityCode          城市code
     */
    private void handlingLogisticsCompanies(List<WebPlatformBO> webPlatformBOList, String provinceCode, String cityCode) {
        WebPlatformBO webPlatformBO = webPlatformBOList.stream().filter(w -> "logistics".equals(w.getName())).findFirst().orElse(null);
        if (webPlatformBO != null) {
            //解析数据
            String logisticsStr = JSONObject.toJSONString(webPlatformBO.getContent());
            JSONObject resp = JSONObject.parseObject(logisticsStr);
            if (resp != null) {
                String logisticsMerchantList = String.valueOf(resp.get("logisticsMerchantList"));
                List<LogisticsVO> logisticsVOS = JSONObject.parseArray(logisticsMerchantList, LogisticsVO.class);
                //获取全部物流公司id
                List<Long> ids = logisticsVOS.stream().map(LogisticsVO::getId).collect(Collectors.toList());
                //根据id获取物流公司的全部信息
                QMemberLogistics qMemberLogistics = QMemberLogistics.memberLogistics;
                BooleanBuilder builder = new BooleanBuilder();
                builder.and(qMemberLogistics.id.in(ids));
                //搜索条件 - 省编码。
                if (org.apache.commons.lang.StringUtils.isNotBlank(provinceCode)) {
                    builder.and(
                            qMemberLogistics.provincesCodeList.like("%" + provinceCode + "%")
                                    .or(qMemberLogistics.provincesCodeList.eq("0"))
                    );
                }
                //搜索条件 - 市编码。
                if (StringUtils.isNotBlank(cityCode)) {
                    builder.and(
                            qMemberLogistics.cityCodeList.like("%" + cityCode + "%")
                                    .or(qMemberLogistics.cityCodeList.eq("0"))
                    );
                }
                List<MemberLogistics> memberLogistics = jpaQueryFactory.select(qMemberLogistics).from(qMemberLogistics).where(builder).fetch();
                List<Long> collect = memberLogistics.stream().map(MemberLogistics::getId).collect(toList());
                logisticsVOS = logisticsVOS.stream().filter(m -> collect.contains(m.getId())).collect(toList());
                resp.put("logisticsMerchantList", logisticsVOS);
                webPlatformBO.setContent(resp);
            }
        }
    }

    @Override
    @ApiOperation(value = "获取使用中的WEB企业商城模板")
    public Wrapper<PageTemplate> findEnterpriseTemplate(SiteIdShopIdDTO dto) {
        return Wrapper.success(pageTemplateRepository.findByEnvironmentAndTypeAndStatusAndSiteIdAndShopId(
                PageTemplateEnvironmentEnum.WEB.getCode(),
                PageTemplateTypeEnum.MALL.getCode(),
                CommonBooleanEnum.YES.getCode(),
                dto.getSiteId(),
                dto.getShopId()
        ));
    }

    @Override
    @ApiOperation(value = "获取使用中的WEB自营商城模板")
    public Wrapper<PageTemplate> findSelfTemplate(Long memberId, Long shopId) {
        //校验
        if (memberId == null || shopId == null) {
            return Wrapper.fail(ResponseCode.PT_PARAMETER_VERIFICATION_FAILED);
        }
        //封装正在使用的自营商城模板
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatus(
                PageTemplateEnvironmentEnum.WEB.getCode(),
                PageTemplateTypeEnum.SELF.getCode(),
                CommonBooleanEnum.YES.getCode()
        );
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            pageTemplateList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseSelfTemplate()) &&
                            a.getUseSelfTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(memberId) && shopId.equals(b.getShopId())
                            )
            ).collect(Collectors.toList());

            if (CollectionUtil.isNotEmpty(pageTemplateList)) {
                if (pageTemplateList.size() > 1) {
                    log.error("正在使用的自营商城模板出现多个【检查原因】");
                }
                PageTemplate pageTemplate = pageTemplateList.get(0);
                pageTemplate.setShopId(pageTemplate.getUseSelfTemplate().get(0).getShopId());
                pageTemplate.setShopName(pageTemplate.getUseSelfTemplate().get(0).getShopName());
                return Wrapper.success(pageTemplate);
            }
        }

        return Wrapper.fail(ResponseCode.PT_THE_SELF_OPERATED_MALL_IN_USE_CANNOT_BE_FOUND);
    }

    @Override
    @ApiOperation(value = "获取使用中的商品描述模板")
    public Wrapper<PageTemplate> findGoodsDescribeTemplate(Long siteId) {
        return Wrapper.success(pageTemplateRepository.findByTypeAndStatusAndSiteId(
                PageTemplateTypeEnum.GOODS.getCode(),
                CommonBooleanEnum.YES.getCode(),
                siteId
        ));
    }

    @Override
    @ApiOperation(value = "根据模板类型获取所有模板")
    public Wrapper<List<PageTemplate>> findAllTemplateByType(PageTemplateTypeDTO dto, UserLoginCacheDTO user) {
        return Wrapper.success(pageTemplateRepository.findByTypeAndSiteIdAndStatusAndAllow(
                dto.getType(),
                dto.getSiteId(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode()
        ));
    }

    @Override
    @ApiOperation(value = "获取模板详情")
    public Wrapper<PageTemplate> findTemplateDetails(IdDTO dto, UserLoginCacheDTO user) {
        return Wrapper.success(pageTemplateRepository.findById(dto.getId()).orElse(null));
    }

    @Override
    @Transactional
    @ApiOperation(value = "上下架模板")
    public Wrapper<Void> shelfTemplate(ShelfTemplateDTO dto, UserLoginCacheDTO user) {
        //根据ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getId()).orElse(null);
        if (pageTemplate == null) {
            throw new BusinessException(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //如果是下架的话, 需要判断模板是否正被使用中
        if (dto.getShelf().equals(PageTemplateShelfEnum.OFF_SHELF.getCode())) {
            if (pageTemplate.getType().equals(PageTemplateTypeEnum.SHOP.getCode()) && CollectionUtil.isNotEmpty(pageTemplate.getUseShopTemplate())) {
                throw new BusinessException(ResponseCode.PT_BY_CANNOT_SOLD_OUT);
            }
            if (pageTemplate.getType().equals(PageTemplateTypeEnum.CHANNEL.getCode()) && CollectionUtil.isNotEmpty(pageTemplate.getUseChannelTemplate())) {
                throw new BusinessException(ResponseCode.PT_BY_CANNOT_SOLD_OUT);
            }
        }

        //修改模板上下架状态
        pageTemplate.setShelf(dto.getShelf());
        pageTemplateRepository.saveAndFlush(pageTemplate);

        return Wrapper.success();
    }

    @Override
    @ApiOperation(value = "获取所有已上架的店铺模板")
    public Wrapper<List<PageTemplateVO>> findAllShelfShopTemplate(UserLoginCacheDTO user) {
        //判断当前登录会员是否有创建店铺, 如果没有, 则让会员跳转创建店铺页
        if (!memberShopRepository.existsByMemberIdAndRoleId(user.getMemberId(), user.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.PT_NOT_CREATE_STORE);
        }

        //获取所有已上架的店铺模板
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByTypeAndShelfAndAllow(
                PageTemplateTypeEnum.SHOP.getCode(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode()
        );

        //拼装返回
        return Wrapper.success(pageTemplateList.stream().map(a -> {
            PageTemplateVO vo = new PageTemplateVO();
            BeanUtils.copyProperties(a, vo);
            vo.setUse(a.getUseShopTemplate().stream().anyMatch(c -> c.getMemberId().equals(user.getMemberId()) && c.getRoleId().equals(user.getMemberRoleId())) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());
            return vo;
        }).collect(Collectors.toList()));
    }

    @Override
    @ApiOperation(value = "获取店铺模板详情")
    public Wrapper<PageTemplateVO> findShopTemplateDetails(IdDTO dto, UserLoginCacheDTO user) {
        //根据ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getId()).orElse(null);
        if (pageTemplate == null) {
            throw new BusinessException(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //拷贝
        PageTemplateVO vo = new PageTemplateVO();
        BeanUtils.copyProperties(pageTemplate, vo);
        //封装当前会员自己的mro开启状态
        List<MemberBO> bos = pageTemplate.getUseShopTemplate().stream().filter(p -> user.getMemberId().equals(p.getMemberId()) && user.getMemberRoleId().equals(p.getRoleId())).collect(toList());
        if (bos.size() > 0) {
            vo.setOpenMro(bos.get(0).getOpenMro());
        }
        //封装当前会员对该店铺模板的使用状态
        vo.setUse(pageTemplate.getUseShopTemplate().stream().anyMatch(c -> c.getMemberId().equals(user.getMemberId()) && c.getRoleId().equals(user.getMemberRoleId())) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());

        //封装正在使用的店铺模板名称
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatusAndShelfAndShopId(
                pageTemplate.getEnvironment(),
                pageTemplate.getType(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode(),
                pageTemplate.getShopId()
        );
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            List<String> nameList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseShopTemplate()) &&
                            a.getUseShopTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId())
                            )
            ).map(PageTemplate::getTemplateName).collect(Collectors.toList());

            if (CollectionUtil.isNotEmpty(nameList)) {
                if (nameList.size() > 1) {
                    log.error("正在使用的店铺模板出现多个【检查原因】");
                }
                vo.setInUseTemplateName(nameList.get(0));
            }
        }

        return Wrapper.success(vo);
    }

    @Override
    @Transactional
    @ApiOperation(value = "使用店铺模板")
    public Wrapper<Void> useShopTemplate(IdDTO dto, UserLoginCacheDTO user) {
        //根据ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getId()).orElse(null);
        if (pageTemplate == null) {
            throw new BusinessException(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //在使用新的店铺模板之前需要将之前正在使用中的相同商城的店铺模板替换（移除被替换店铺模板的当前会员角色）
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatusAndShelfAndShopId(
                pageTemplate.getEnvironment(),
                pageTemplate.getType(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode(),
                pageTemplate.getShopId()
        );
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            List<PageTemplate> useTemplateList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseShopTemplate()) &&
                            a.getUseShopTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId())
                            )
            ).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(useTemplateList)) {
                if (useTemplateList.size() > 1) {
                    log.error("正在使用的店铺模板出现多个【检查原因】");
                }
                pageTemplateRepository.saveAll(
                        useTemplateList.stream().peek(a -> a.setUseShopTemplate(
                                a.getUseShopTemplate().stream().filter(b ->
                                        !(b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId()))
                                ).collect(Collectors.toList())
                        )).collect(Collectors.toList())
                );
            }
        }

        //添加当前会员到店铺模板使用人内
        MemberBO memberBO = new MemberBO();
        memberBO.setMemberId(user.getMemberId());
        memberBO.setRoleId(user.getMemberRoleId());
        pageTemplate.getUseShopTemplate().add(memberBO);
        pageTemplateRepository.saveAndFlush(pageTemplate);

        return Wrapper.success();
    }

    @Override
    @ApiOperation(value = "获取所有已上架的渠道模板")
    public Wrapper<List<PageTemplateVO>> findAllShelfChannelTemplate(UserLoginCacheDTO user) {
        //判断当前登录会员是否有创建渠道, 如果没有, 则让会员跳转创建渠道页
        if (!memberChannelRepository.existsByMemberIdAndRoleId(user.getMemberId(), user.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.PT_NOT_CREATE_CHANNEL);
        }

        //获取所有已上架的渠道模板
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByTypeAndShelfAndAllow(
                PageTemplateTypeEnum.CHANNEL.getCode(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode()
        );

        //拼装返回
        return Wrapper.success(pageTemplateList.stream().map(a -> {
            PageTemplateVO vo = new PageTemplateVO();
            BeanUtils.copyProperties(a, vo);
            vo.setUse(a.getUseChannelTemplate().stream().anyMatch(c -> c.getMemberId().equals(user.getMemberId()) && c.getRoleId().equals(user.getMemberRoleId())) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());
            return vo;
        }).collect(Collectors.toList()));
    }

    @Override
    @ApiOperation(value = "获取渠道模板详情")
    public Wrapper<PageTemplateVO> findChannelTemplateDetails(IdDTO dto, UserLoginCacheDTO user) {
        //根据ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getId()).orElse(null);
        if (pageTemplate == null) {
            throw new BusinessException(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //拷贝
        PageTemplateVO vo = new PageTemplateVO();
        BeanUtils.copyProperties(pageTemplate, vo);
        //封装当前会员自己的mro开启状态
        List<MemberBO> bos = pageTemplate.getUseChannelTemplate().stream().filter(p -> user.getMemberId().equals(p.getMemberId()) && user.getMemberRoleId().equals(p.getRoleId())).collect(toList());
        if (bos.size() > 0) {
            vo.setOpenMro(bos.get(0).getOpenMro());
        }
        //封装当前会员对该渠道模板的使用状态
        vo.setUse(pageTemplate.getUseChannelTemplate().stream().anyMatch(c -> c.getMemberId().equals(user.getMemberId()) && c.getRoleId().equals(user.getMemberRoleId())) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());

        //封装正在使用的渠道模板名称
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatusAndShelfAndShopId(
                pageTemplate.getEnvironment(),
                pageTemplate.getType(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode(),
                pageTemplate.getShopId()
        );
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            List<String> nameList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseChannelTemplate()) &&
                            a.getUseChannelTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId())
                            )
            ).map(PageTemplate::getTemplateName).collect(Collectors.toList());

            if (CollectionUtil.isNotEmpty(nameList)) {
                if (nameList.size() > 1) {
                    log.error("正在使用的渠道模板出现多个【检查原因】");
                }
                vo.setInUseTemplateName(nameList.get(0));
            }
        }

        return Wrapper.success(vo);
    }

    @Override
    @Transactional
    @ApiOperation(value = "使用渠道模板")
    public Wrapper<Void> useChannelTemplate(IdDTO dto, UserLoginCacheDTO user) {
        //根据ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getId()).orElse(null);
        if (pageTemplate == null) {
            throw new BusinessException(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //在使用新的渠道模板之前需要将之前正在使用中的相同商城的渠道模板替换（移除被替换渠道模板的当前会员角色）
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatusAndShelfAndShopId(
                pageTemplate.getEnvironment(),
                pageTemplate.getType(),
                CommonBooleanEnum.YES.getCode(),
                CommonBooleanEnum.YES.getCode(),
                pageTemplate.getShopId()
        );
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            List<PageTemplate> useTemplateList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseChannelTemplate()) &&
                            a.getUseChannelTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId())
                            )
            ).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(useTemplateList)) {
                if (useTemplateList.size() > 1) {
                    log.error("正在使用的渠道模板出现多个【检查原因】");
                }
                pageTemplateRepository.saveAll(
                        useTemplateList.stream().peek(a -> a.setUseChannelTemplate(
                                a.getUseChannelTemplate().stream().filter(b ->
                                        !(b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId()))
                                ).collect(Collectors.toList())
                        )).collect(Collectors.toList())
                );
            }
        }

        //添加当前会员到渠道模板使用人内
        MemberBO memberBO = new MemberBO();
        memberBO.setMemberId(user.getMemberId());
        memberBO.setRoleId(user.getMemberRoleId());
        pageTemplate.getUseChannelTemplate().add(memberBO);
        pageTemplateRepository.saveAndFlush(pageTemplate);

        return Wrapper.success();
    }

    @Override
    @ApiOperation(value = "获取所有活动模板")
    public Wrapper<PageData<PageTemplate>> findAllActivityTemplate(PageVO dto, Integer environment) {
        if (environment == null) {
            return Wrapper.fail(ResponseCode.PT_MALL_ENVIRONMENT_CANNOT_BE_EMPTY);
        }

        Page<PageTemplate> page = pageTemplateRepository.findByEnvironmentAndTypeAndAllow(
                environment,
                PageTemplateTypeEnum.ACTIVITY.getCode(),
                CommonBooleanEnum.YES.getCode(),
                PageRequest.of(dto.getCurrent() - 1, dto.getPageSize())
        );

        return Wrapper.success(new PageData<>(page.getTotalElements(), page.getContent()));
    }

    @Override
    @ApiOperation(value = "获取所有自营商城模板")
    public Wrapper<List<PageTemplateVO>> findAllSelfTemplate(UserLoginCacheDTO user) {
        //获取所有允许使用的自营商城模板
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByTypeAndAllow(
                PageTemplateTypeEnum.SELF.getCode(),
                CommonBooleanEnum.YES.getCode()
        );

        //拼装返回
        return Wrapper.success(pageTemplateList.stream().map(a -> {
            PageTemplateVO vo = new PageTemplateVO();
            BeanUtils.copyProperties(a, vo);
            a.getUseSelfTemplate().forEach(b -> {
                if (b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId())) {
                    vo.setShopId(b.getShopId());
                    vo.setShopName(b.getShopName());
                }
            });
            vo.setUse(a.getUseSelfTemplate().stream().anyMatch(c -> c.getMemberId().equals(user.getMemberId()) && c.getRoleId().equals(user.getMemberRoleId())) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());
            return vo;
        }).collect(Collectors.toList()));
    }

    @Override
    @ApiOperation(value = "获取自营商城模板详情")
    public Wrapper<PageTemplateVO> findSelfTemplateDetails(IdDTO dto, UserLoginCacheDTO user) {
        //根据ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getId()).orElse(null);
        if (pageTemplate == null) {
            throw new BusinessException(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //拷贝
        PageTemplateVO vo = new PageTemplateVO();
        BeanUtils.copyProperties(pageTemplate, vo);
        vo.setSourceShopId(pageTemplate.getShopId());
        vo.setSourceShopName(pageTemplate.getShopName());
        //获取当前用户自己商城id和名称(一个会员同一个模板只会用一个)
        List<SelfMemberBO> useSelfTemplate = pageTemplate.getUseSelfTemplate();
        if (useSelfTemplate.size() > 0) {
            List<SelfMemberBO> selfMemberBOS = useSelfTemplate.stream().filter(a -> a.getMemberId().equals(user.getMemberId()) && a.getRoleId().equals(user.getMemberRoleId())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(selfMemberBOS)) {
                vo.setShopId(selfMemberBOS.get(0).getShopId());
                vo.setShopName(selfMemberBOS.get(0).getShopName());
                vo.setOpenMro(selfMemberBOS.get(0).getOpenMro());
            }
        }

        //封装当前会员对该自营模板的使用状态
        vo.setUse(pageTemplate.getUseSelfTemplate().stream().anyMatch(c -> c.getMemberId().equals(user.getMemberId()) && c.getRoleId().equals(user.getMemberRoleId())) ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode());

        //封装正在使用的自营模板名称
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatus(
                pageTemplate.getEnvironment(),
                pageTemplate.getType(),
                CommonBooleanEnum.YES.getCode()
        );
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            List<String> nameList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseSelfTemplate()) &&
                            a.getUseSelfTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId()) && vo.getShopId() != null && vo.getShopId().equals(b.getShopId())
                            )
            ).map(PageTemplate::getTemplateName).collect(Collectors.toList());

            if (CollectionUtil.isNotEmpty(nameList)) {
                if (nameList.size() > 1) {
                    return Wrapper.fail(ResponseCode.PT_MULTIPLE_SHOP_TEMPLATES_IN_USE);
                }
                vo.setInUseTemplateName(nameList.get(0));
            }
        }

        return Wrapper.success(vo);
    }

    @Override
    @Transactional
    @ApiOperation(value = "使用自营商城模板")
    public Wrapper<Void> useSelfTemplate(TemplateInfoDTO dto, UserLoginCacheDTO user) {
        //根据ID获取模板
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getId()).orElse(null);
        if (pageTemplate == null) {
            return Wrapper.fail(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }

        //在使用新的自营商城模板之前需要将之前同一个用户正在使用中的相同商城的自营商城模板替换（移除被替换自营商城模板的当前会员角色）
        List<PageTemplate> pageTemplateList = pageTemplateRepository.findByEnvironmentAndTypeAndStatus(
                pageTemplate.getEnvironment(),
                pageTemplate.getType(),
                CommonBooleanEnum.YES.getCode()
        );
        //获取自营商城模板当前的使用者是否包含当前登录会员
        if (CollectionUtil.isNotEmpty(pageTemplateList)) {
            List<PageTemplate> useTemplateList = pageTemplateList.stream().filter(a ->
                    CollectionUtil.isNotEmpty(a.getUseSelfTemplate()) &&
                            a.getUseSelfTemplate().stream().anyMatch(b ->
                                    b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId()) && dto.getShopId().equals(b.getShopId())
                            )
            ).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(useTemplateList)) {
                if (useTemplateList.size() > 1) {
                    log.info(ResponseCode.PT_MULTIPLE_STORE_TEMPLATES_IN_USE.getMessage());
                }
                pageTemplateRepository.saveAll(
                        useTemplateList.stream().peek(a -> a.setUseSelfTemplate(
                                a.getUseSelfTemplate().stream().filter(b ->
                                        !(b.getMemberId().equals(user.getMemberId()) && b.getRoleId().equals(user.getMemberRoleId()))
                                ).collect(Collectors.toList())
                        )).collect(Collectors.toList())
                );
            }
        }

        //添加当前会员到自营模板使用人内
        SelfMemberBO memberBO = new SelfMemberBO();
        memberBO.setMemberId(user.getMemberId());
        memberBO.setRoleId(user.getMemberRoleId());
        //赋值自己使用的自营商城信息
        memberBO.setShopId(dto.getShopId());
        memberBO.setShopName(dto.getShopName());
        pageTemplate.getUseSelfTemplate().add(memberBO);
        pageTemplateRepository.saveAndFlush(pageTemplate);

        return Wrapper.success();
    }

    /**
     * 启用/停用mro模式
     *
     * @param openMroDTO 请求参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> openMro(OpenMroDTO openMroDTO, UserLoginCacheDTO user) {
        //判断模板是否存在
        PageTemplate pageTemplate = pageTemplateRepository.findById(openMroDTO.getTemplateId()).orElse(null);
        if (pageTemplate == null) {
            return Wrapper.fail(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }
        switch (pageTemplate.getType()) {
            case 1:     //操作联营
                pageTemplate.setOpenMro(openMroDTO.getOpenMro());
                break;
            case 2:     //操作店铺
                storeOpenMro(user, pageTemplate, openMroDTO);
                break;
            case 4:    //操作渠道
                channelShopOpenMro(user, pageTemplate, openMroDTO);
                break;
            case 6:    //操作自营
                selfShopOpenMro(user, pageTemplate, openMroDTO);
                break;
            default:
                break;
        }
        pageTemplateRepository.saveAndFlush(pageTemplate);
        return Wrapper.success();
    }

    private void channelShopOpenMro(UserLoginCacheDTO user, PageTemplate pageTemplate, OpenMroDTO openMroDTO) {
        if (user == null) {
            throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
        }
        List<MemberBO> useChannelTemplate = pageTemplate.getUseChannelTemplate();
        if (CollectionUtils.isEmpty(useChannelTemplate) || CollectionUtils.isEmpty(useChannelTemplate.stream().filter(e -> user.getMemberId().equals(e.getMemberId()) && user.getMemberRoleId().equals(e.getRoleId())).collect(toList()))) {
            MemberBO bo = new MemberBO();
            bo.setOpenMro(openMroDTO.getOpenMro());
            bo.setMemberId(user.getMemberId());
            bo.setRoleId(user.getMemberRoleId());
            useChannelTemplate.add(bo);
            pageTemplate.setUseChannelTemplate(useChannelTemplate);
        } else {
            MemberBO selfMemberBO = useChannelTemplate.stream().filter(e -> user.getMemberId().equals(e.getMemberId()) && user.getMemberRoleId().equals(e.getRoleId())).collect(toList()).get(0);
            selfMemberBO.setOpenMro(openMroDTO.getOpenMro());
            pageTemplate.setUseChannelTemplate(useChannelTemplate);
        }
    }

    private void storeOpenMro(UserLoginCacheDTO user, PageTemplate pageTemplate, OpenMroDTO openMroDTO) {
        if (user == null) {
            throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
        }
        List<MemberBO> useShopTemplate = pageTemplate.getUseShopTemplate();
        if (CollectionUtils.isEmpty(useShopTemplate) || CollectionUtils.isEmpty(useShopTemplate.stream().filter(e -> user.getMemberId().equals(e.getMemberId()) && user.getMemberRoleId().equals(e.getRoleId())).collect(toList()))) {
            MemberBO bo = new MemberBO();
            bo.setOpenMro(openMroDTO.getOpenMro());
            bo.setMemberId(user.getMemberId());
            bo.setRoleId(user.getMemberRoleId());
            useShopTemplate.add(bo);
            pageTemplate.setUseShopTemplate(useShopTemplate);
        } else {
            MemberBO selfMemberBO = useShopTemplate.stream().filter(e -> user.getMemberId().equals(e.getMemberId()) && user.getMemberRoleId().equals(e.getRoleId())).collect(toList()).get(0);
            selfMemberBO.setOpenMro(openMroDTO.getOpenMro());
            pageTemplate.setUseShopTemplate(useShopTemplate);
        }
    }

    private void selfShopOpenMro(UserLoginCacheDTO user, PageTemplate pageTemplate, OpenMroDTO openMroDTO) {
        if (user == null) {
            throw new BusinessException(ResponseCode.TOKEN_DOES_NOT_EXIST_IN_CACHE);
        }
        List<SelfMemberBO> useSelfTemplate = pageTemplate.getUseSelfTemplate();
        if (CollectionUtils.isEmpty(useSelfTemplate) || CollectionUtils.isEmpty(useSelfTemplate.stream().filter(e -> user.getMemberId().equals(e.getMemberId()) && user.getMemberRoleId().equals(e.getRoleId())).collect(toList()))) {
            SelfMemberBO bo = new SelfMemberBO();
            bo.setOpenMro(openMroDTO.getOpenMro());
            bo.setMemberId(user.getMemberId());
            bo.setRoleId(user.getMemberRoleId());
            bo.setShopId(pageTemplate.getShopId());
            bo.setShopName(pageTemplate.getShopName());
            useSelfTemplate.add(bo);
            pageTemplate.setUseSelfTemplate(useSelfTemplate);
        } else {
            SelfMemberBO selfMemberBO = useSelfTemplate.stream().filter(e -> user.getMemberId().equals(e.getMemberId()) && user.getMemberRoleId().equals(e.getRoleId())).collect(toList()).get(0);
            selfMemberBO.setOpenMro(openMroDTO.getOpenMro());
            pageTemplate.setUseSelfTemplate(useSelfTemplate);
        }

    }


    @Override
    public Wrapper<Boolean> openMroInner(OpenMroInnerDTO dto) {
        PageTemplate pageTemplate = pageTemplateRepository.findById(dto.getTemplateId()).orElse(null);
        if (pageTemplate == null) {
            return Wrapper.fail(ResponseCode.PT_NOT_FOUND_TEMPLATE);
        }
        //查询店铺,企业,渠道商城模板
        if (dto.getShopId() < 1000) {
            return Wrapper.success(pageTemplate.getOpenMro() == 1);//开启返回true,不开启返回false
        } else {
            if (dto.getMemberId() == null || dto.getRoleId() == null) {
                return Wrapper.fail(ResponseCode.PT_MEMBER_INFORMATION_CANNOT_BE_EMPTY);
            }
            SelfMemberBO selfMemberBO = pageTemplate.getUseSelfTemplate().stream().filter(e -> dto.getMemberId().equals(e.getMemberId()) && dto.getRoleId().equals(e.getRoleId()) && dto.getShopId().equals(e.getShopId())).collect(toList()).get(0);
            return Wrapper.success(selfMemberBO.getOpenMro() == CommonBooleanEnum.YES.getCode());
        }

    }
}
